package com.haisen.service.impl;

import com.alibaba.fastjson.JSON;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.haisen.dataobject.entity.TokenDing;
import com.haisen.dataobject.mapper.base.TokenDingMapper;
import com.haisen.dataobject.vo.DingH5TokenVO;
import com.haisen.exception.BizException;
import com.haisen.service.DingTokenServcie;
import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import java.util.Calendar;
import java.util.logging.Handler;

@Service
@Slf4j
public class DingTokenServiceImpl implements DingTokenServcie{

    @Autowired
    private TokenDingMapper tokenDingMapper;

    @Value("${auth.dingding.h5AppId}")
    private String h5AppId;

    @Value("${auth.dingding.h5AppSecret}")
    private String h5AppSecret;
    //对象ehcache中的name
   // @Value("${auth.dingding.tokenCachName}")
    private static  final String  CACHE_NAME = "dingh5wximpTokenCache";
   // @Value("${auth.dingding.tokenCacheKey}")
    public static  final String TOKEN_KEY ="dingH5WximpToken" ;

    /**
     * 如果不存在就插入，存在就更新
     * @param tokenDing
     */
    @Override
    @CacheEvict(value = CACHE_NAME ,key = "'"+TOKEN_KEY+"'")
    public void  create(TokenDing tokenDing) {
        log.info("插入数据库，token={}",JSON.toJSONString(tokenDing));
        tokenDingMapper.insertSelective(tokenDing);
    }



    @Override
    @CachePut(value = CACHE_NAME,key =  "'"+TOKEN_KEY+"'")
    public TokenDing update(TokenDing tokenDing) {
       log.info("数据库更新token，删除缓存token");
        Weekend<TokenDing> example = Weekend.of(TokenDing.class);
        WeekendCriteria<TokenDing,Object> criteria = example.weekendCriteria();
        criteria.andEqualTo(TokenDing::getTokenKey,tokenDing.getTokenKey());
      tokenDingMapper.updateByExampleSelective(tokenDing,example);
     return tokenDing;
    }

    @CacheEvict(value = CACHE_NAME,key =  "'"+TOKEN_KEY+"'")
    @Override
    public void delete(String key) {
        Weekend<TokenDing> example = Weekend.of(TokenDing.class);
        WeekendCriteria<TokenDing,Object> criteria = example.weekendCriteria();
        criteria.andEqualTo(TokenDing::getTokenKey,key);
       log.info("删除token");
      tokenDingMapper.deleteByExample(example);
    }

    @Override
    @Cacheable(value = CACHE_NAME,key =  "'"+TOKEN_KEY+"'")
    public TokenDing load(String key) {
        Weekend<TokenDing> example = Weekend.of(TokenDing.class);
        WeekendCriteria<TokenDing,Object> criteria = example.weekendCriteria();
        criteria.andEqualTo(TokenDing::getTokenKey,key);
         TokenDing tokenDing = tokenDingMapper.selectOneByExample(example);
        log.info("从数据库读取token！{}" , JSON.toJSONString(tokenDing));
        return tokenDing;
    }


    public String requestToken(){
        //1提交请求，获取token
        DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
        OapiGettokenRequest request = new OapiGettokenRequest();
        request.setAppkey(h5AppId);
        request.setAppsecret(h5AppSecret);
        request.setHttpMethod("GET");
        try {
            OapiGettokenResponse response = client.execute(request);
             if (response.getErrcode() != 0){
                 throw new BizException("获取令牌失败");
             }
             return response.getAccessToken();

        } catch (ApiException exception){
            throw  new BizException(exception.getErrMsg());
        }
    }

    @Override
    public TokenDing forceUpdateToken(TokenDing tokenDing){
        tokenDing = initToken(tokenDing);
        update(tokenDing);
        return tokenDing;
    }

   public TokenDing tokenHandler(){
       TokenDing tokenDing = load(TOKEN_KEY);
       if (tokenDing == null){
           tokenDing = new TokenDing();
           tokenDing = initToken(tokenDing);
           //设置过期时间为600秒,多次更新
           create(tokenDing);
       } else{
           if (Calendar.getInstance().getTime().getTime() > tokenDing.getExpiretime()){
               tokenDing = initToken(tokenDing);
               update(tokenDing);
           }
       }
       return tokenDing;
   }


    private TokenDing initToken(TokenDing tokenDing) {
        Calendar calendar = Calendar.getInstance();
        String token = requestToken();
        tokenDing.setToken(token);
        tokenDing.setTokenKey(TOKEN_KEY);
        tokenDing.setCreatetime(calendar.getTime().getTime());
        calendar.add(Calendar.SECOND,600);
        tokenDing.setExpiretime(calendar.getTime().getTime());
        return tokenDing;
    }

}
